package com.leyou.trade.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.utils.UserContext;
import com.leyou.common.exceptions.LyException;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.trade.dto.OrderFormDTO;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.OrderDetail;
import com.leyou.trade.entity.OrderLogistics;
import com.leyou.trade.enums.OrderStatus;
import com.leyou.trade.mapper.OrderMapper;
import com.leyou.trade.service.CartService;
import com.leyou.trade.service.OrderDetailService;
import com.leyou.trade.service.OrderLogisticsService;
import com.leyou.trade.service.OrderService;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.AddressDTO;
import feign.FeignException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private ItemClient itemClient;
    @Autowired
    private OrderDetailService detailService;
    @Autowired
    private OrderLogisticsService logisticsService;
    @Autowired
    private UserClient userClient;
    @Autowired
    private CartService cartService;
    //创建订单
    @Override
    @Transactional
    public Long createOrder(@Valid OrderFormDTO orderFormDTO) {
        //1.添加order
        Order order = new Order();
        //1.1用户id
        Long userId = UserContext.getUser().getId();
        order.setUserId(userId);
        //1.2金额相关数据
        Map<Long, Integer> carts = orderFormDTO.getCarts();
        //获取所有sku的id
        List<Long> idList = new ArrayList<>(carts.keySet());
        List<SkuDTO> skuDTOS = itemClient.querySkuByIds(idList);
        //计算总金额
        long total = 0;
        for (SkuDTO skuDTO : skuDTOS) {
            // 判断商品状态
            if (!skuDTO.getSaleable()) {
                // 商品下架
                throw new LyException(400, "商品已经下架，无法下单");
            }
            Integer num = carts.get(skuDTO.getId());
            total += skuDTO.getPrice() * num;
        }
        order.setTotalFee(total);
        order.setPaymentType(orderFormDTO.getPaymentType());

        // TODO 1.1.5.根据物流算运费，目前全场包邮
        order.setPostFee(0L);
        //TODO 根据商品算优惠，目前没有优惠
        order.setActualFee(total+order.getPostFee());
        //1.3设置订单状态
        order.setStatus(OrderStatus.INIT.getValue());
        //1.4写order到数据库
        boolean success = save(order);

        // 2.添加OrderDetail
        //2.1.定义一个OrderDetail的集合
        List<OrderDetail> details = new ArrayList<>();
        //2.2.遍历sku集合，转为detail
        for (SkuDTO skuDTO : skuDTOS) {
            OrderDetail detail = new OrderDetail();
            detail.setTitle(skuDTO.getTitle());
            detail.setSpec(skuDTO.getSpecialSpec());
            detail.setSkuId(skuDTO.getId());
            detail.setPrice(skuDTO.getPrice());
            detail.setOrderId(order.getOrderId());
            detail.setNum(carts.get(skuDTO.getId()));
            detail.setImage(StringUtils.substringBefore(skuDTO.getImages(), ","));

            //装入detail集合
            details.add(detail);
        }
        //2.3批量写入OrderDetail
        success = detailService.saveBatch(details);
        if(!success){
            throw new LyException(500, "订单创建失败！");
        }

        //3.新增orderLogistics物流信息
        //查询收货地址
        AddressDTO address = userClient.queryAddressById(orderFormDTO.getAddressId());
        //填写物流信息
        OrderLogistics logistics = address.toEntity(OrderLogistics.class);
        logistics.setOrderId(order.getOrderId());
        //写入数据库
        success = logisticsService.save(logistics);
        if(!success){
            throw new LyException(500, "订单创建失败！");
        }
        // 4.减库存
        try {
            itemClient.deductStock(carts);
        } catch (FeignException e) {
            throw new LyException(e.status(), e.contentUTF8());
        }

        // 5.删除购物车中已经下单的商品
        for (Long skuId : idList) {
            cartService.deleteCart(skuId);
        }
        return order.getOrderId();
    }
}
